package cool.webstudy.admin.utils.scheduler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @author think
 * @date 2025/2/20 13:08
 * @description: Runnable接口实现类
 */
public class SchedulerRunnable implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(SchedulerRunnable.class);

    private String unCode;

    private String beanName;

    private String methodName;

    private String params;


    public SchedulerRunnable(String beanName, String methodName) {
        this(beanName, methodName, null, null);
    }

    public SchedulerRunnable(String unCode, String beanName, String methodName, String params) {
        this.unCode = unCode;
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
    }

    @Override
    public void run() {
        logger.info("定时任务开始执行 - 业务主键：{}，bean：{}，方法：{}，参数：{}", unCode, beanName, methodName, params);
        long startTime = System.currentTimeMillis();

        try {
            Object target = SpringContextUtils.getBean(beanName);

            Method method = null;
            if (!StringUtils.isEmpty(params)) {
                method = target.getClass().getDeclaredMethod(methodName, String.class);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }

            ReflectionUtils.makeAccessible(method);
            if (!StringUtils.isEmpty(params)) {
                method.invoke(target, params);
            } else {
                method.invoke(target);
            }
        } catch (Exception ex) {
            logger.error(String.format("定时任务执行异常 - bean：%s，方法：%s，参数：%s ", beanName, methodName, params), ex);
        }

        long times = System.currentTimeMillis() - startTime;
        logger.info("定时任务执行结束 - bean：{}，方法：{}，参数：{}，耗时：{} 毫秒", beanName, methodName, params, times);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SchedulerRunnable that = (SchedulerRunnable) o;
        if (params == null) {
            return unCode.equals(that.unCode) && beanName.equals(that.beanName) &&
                    methodName.equals(that.methodName) &&
                    that.params == null;
        }

        return unCode.equals(that.unCode) && beanName.equals(that.beanName) &&
                methodName.equals(that.methodName) &&
                params.equals(that.params);
    }

    @Override
    public int hashCode() {
        if (params == null) {
            return Objects.hash(unCode, beanName, methodName);
        }

        return Objects.hash(unCode, beanName, methodName, params);
    }
}
